#if !defined(MERGE_UNIQUE_H)
#define MERGE_UNIQUE_H
// merge_unique.h : helper functions and macros
//
/////////////////////////////////////////////////////////////////////////////


#include <algorithm>
#include <iterator>
#include <functional>

/*****************************************************************************************
						merge_unique

******************************************************************************************/
template<typename t_forward_iterator, typename t_binary_predicate, typename t_binary_op>
t_forward_iterator
merge_unique(t_forward_iterator first, t_forward_iterator last,
			 t_binary_predicate binary_pred, t_binary_op binary_op)
{
	// Skip the beginning, if already unique.
	first = std::adjacent_find(first, last, binary_pred);
	if (first == last)
		return last;

	// Do the real work.
	t_forward_iterator dest = first;
//	++first;
	while (++first != last)
		if (!binary_pred(*dest, *first))
			*++dest = *first;
		else
			binary_op(*dest, *first);
	return ++dest;
}


/*****************************************************************************************
						merge_unique

******************************************************************************************/
template<typename CONT, typename t_binary_predicate, typename t_binary_op>
void merge_unique(CONT& container, t_binary_predicate binary_pred, t_binary_op binary_op)
{
	typedef typename CONT::iterator iter;
	iter first = container.begin();
	iter last = container.end();

	// Skip the beginning, if already unique.
	first = std::adjacent_find(first, last, binary_pred);
	if (first == last)
		return;

	// Do the real work.
	iter dest = first;
//	++first;
	while (++first != last)
		if (!binary_pred(*dest, *first))
			*++dest = *first;
		else
			binary_op(*dest, *first);
	container.erase(++dest, container.end());
}

#endif	//MERGE_UNIQUE_H
